home *** CD-ROM | disk | FTP | other *** search
- NAME mssser
- ; File MSSSER.ASM
- include mssdef.h
- ; Copyright (C) 1985, 1993, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or institution
- ; to use this software as long as it is not sold for profit. This copyright
- ; notice must be retained. This software may not be included in commercial
- ; products without written permission of Columbia University.
- ;
- ; Edit history:
- ; 27 August 1992 version 3.13
- ; 6 Sept 1991 version 3.11
- ; Last edit 19 April 1993
-
- public bye, finish, remote, get, server, denyflg, srvtmo
- public luser, lpass
-
- data segment
- extrn flags:byte, trans:byte, curdsk:byte, diskio:byte, auxfile:byte
- extrn comand:byte, filtst:byte, maxtry:byte, dtrans:byte
- extrn fmtdsp:byte, errlev:byte, fsta:word, kstatus:word
- extrn rpacket:byte, encbuf:byte, decbuf:byte, sstate:byte
- extrn rstate:byte, pktnum:byte, windlow:byte, takadr:word
- extrn prmptr:word, chkparflg:byte
-
- scrser equ 0209H ; place for server state display line
- scrmsg equ 0e16H ; place for Last message
-
- remcmd db 0 ; Remote command to be executed
- rempac db 0 ; Packet type: C (host) or G (generic)
- remlen db 0 ; length of following text field
-
- ermes6 db 'Filename too long for packet',0
- cemsg db 'User intervention',0
- infms1 db 'Server mode: type C or Control-C to exit',cr,lf,'$'
- infms2 db cr,lf,'?More parameters are needed$'
- infms3 db 'REMOTE command reply',0 ; for transaction logging
- infms4 db 'Help text',0 ; filename for REM Help reply
- inthlp db cr,lf,' Time-limit to remain in Server mode, seconds or'
- db ' specific hh:mm:ss (24h clock).'
- db cr,lf,' SET TIMER ON to time. Return for no time limit.$'
- remms1 db ' Unknown server command',0
- remms2 db ' Invalid login information',0
- remms3 db ' Kermit-MS Server ready',0
- remms5 db ' File not found',0
- remms6 db ' Command failed',0
- remms7 db ' REMOTE LOGIN is required',0
- remms8 db ' Command succeeded',0
- remms9 db ' Command is Disabled',0
- remms10 db ' Could not create work file',0
- byemsg db ' Goodbye!',0
- whomsg db ' Just this Server',0
- spcmsg db ' bytes available on drive ' ; remote space responses
- spcmsg1 db ' ',0
- spcmsg2 db ' Drive '
- spcmsg3 db ' : is not ready',0
- user db ' Username: ',0 ; for Remote Login, asciiz
- password db ' Password: ',0 ; for Remote Login and Remote CD
- account db ' Account: ',0 ; for Remote Login
- slogin db 0 ; non-zero if successful local login
- luser db 17 dup (0) ; local Username, case insenstitive
- lpass db 17 dup (0) ; local Password, case sensitive
- srvtmp db ' > :$kermit$.tmp',0 ; asciiz, kermit's temp output file
- delstr db 'del ',0
- dirstr db 'dir ',0
- crlf db cr,lf,'$'
- emptymsg db 0 ; empty asciiz msg
- skertmp dw 0 ; REMOTE KERMIT work word
- denyflg dw 0 ; bit field of denied commands
- temp dw 0
- temp2 dw 0
- cnt dw 0
- bufptr dw 0
- dsptmp db 0 ; temp to hold fmtdsp during serving
- srvtmo db 0 ; idle NAK time, default is no NAKs
- srvtime db 0 ; non-zero if timing Server residence
- remfnm db ' Remote Source File: ',0 ; asciiz
- lclfnm db ' Local Destination File: ',0 ; asciiz
- filhlp db ' File name to use locally$'
- filmsg db ' Remote filename, or press ENTER for prompts$'
- frem db ' Name of file on remote system $'
- genmsg db ' Enter text to be sent to remote server $'
- numhlp db ' number$'
- xfrhlp db ' character set identifier string$'
- tmpbuf db 20 dup (0)
- srvbuf db 80 dup (0) ; place After tmpbuf, for status
-
- savflg flginfo <> ; save area for flags.*
- savflgl equ $-savflg ; length
- savdtr trinfo <> ; save area for dtrans.*
- savdtrl equ $-savdtr ; length
- savtr trinfo <> ; save area for trans.*
- savmaxtry db 0 ; save area for maxtry
-
- srvchr db 'SRGIECK' ; server cmd characters, use w/srvfun
- srvfln equ $-srvchr ; length of table
-
- srvfun dw srvsnd,srvrcv,srvgen,srvini,srverr,srvhos,srvker ; for srvchr
-
- srvch2 db 'CDEFHLMSTUW' ; server commands, use with srvdsp
- srvfl2 equ $-srvch2
-
- srvdsp dw srvcwd,srvdir,srvdel,srvfin,srvhlp,srvlog,srvmsg
- dw srvset,srvtyp,srvspc,srvwho
-
- remhlp db cr,lf,' Command Action performed by the server Kermit'
- db cr,lf,' ------- -------------------------------------'
- db cr,lf,' CD/CWD change working directory' ; Answer to
- db cr,lf,' Delete a file' ; local
- db cr,lf,' Directory filespec' ; REM HELP
- db cr,lf,' Help show server''s remote help screen'
- db cr,lf,' Host command (to remote operating system)'
- db cr,lf,' Kermit command (to Kermit server)'
- db cr,lf,' Login name password to a Kermit server'
- db cr,lf,' Logout exit remote Kermit (but keep remote host)'
- db cr,lf,' Message short one line message'
- db cr,lf,' Print local file (on server''s printer)'
- db cr,lf,' Set command (modify server)'
- db cr,lf,' Space drive/directory'
- db cr,lf,' Type a file on this screen'
- db cr,lf,' Who user parameters$'
-
- ; Answer from Server to REMOTE HELP
- hlprem db cr,lf,'Kermit-MS Server commands:',lf
- db cr,lf,'GET filespec '
- db 'REMOTE DIRECTORY filespec REMOTE PRINT filespec'
- db cr,lf,'SEND filespec '
- db 'REMOTE HELP this text REMOTE SET command'
- db cr,lf,'BYE, FINISH, REMOTE LOGOUT'
- db 'REMOTE HOST command REMOTE SPACE drive-letter'
- db cr,lf,'REMOTE CD/CWD directory '
- db 'REMOTE LOGIN name password REMOTE TYPE filespec'
- db cr,lf,'REMOTE DELETE filespec '
- db 'REMOTE MESSAGE 1-line msg REMOTE WHO'
- db 0
-
- remtab db 15 ; 15 entries
- mkeyw 'CD',remcwd
- mkeyw 'CWD',remcwd
- mkeyw 'Delete',remdel
- mkeyw 'Directory',remdir
- mkeyw 'Help',remhel
- mkeyw 'Host',remhos
- mkeyw 'Kermit',remker
- mkeyw 'Login',remlogin
- mkeyw 'Logout',remlogout
- mkeyw 'Message',remmsg
- mkeyw 'Print',remprn ; top of SEND procedure in msssen
- mkeyw 'Set',remset
- mkeyw 'Space',remdis
- mkeyw 'Type',remtyp
- mkeyw 'Who',remwho
-
- setval dw 300,302,310 ; answer REMOTE SET workers
- dw 400,401,402,403,404,405,406
- setvlen equ ($-setval)/2 ; number of entries
- setvec dw sftype,sfcoll,sfinc ; routines paralleling setval
- dw sblkck,srpkt,srtmo,sretry,sstmo,sxfrch,swind
-
- remstt1 db 9 ; REMOTE SET top level table
- mkeyw 'Attributes',1
- mkeyw 'File',2
- mkeyw 'Incomplete',310
- mkeyw 'Block-check',400
- mkeyw 'Receive',3
- mkeyw 'Retry',403
- mkeyw 'Server',404
- mkeyw 'Transfer',405
- mkeyw 'Window-slots',406
-
- remsat1 db 2 ; REMOTE SET ATTRIBUTES
- mkeyw 'IN',0
- mkeyw 'OUT',100
-
- remsat2 db 17 ; REMOTE ATTRIBUTES {IN} item
- ; REM ATT {OUT} item is 100 greater
- mkeyw 'All',132
- mkeyw 'Length',133
- mkeyw 'Type',134
- mkeyw 'Date',135
- mkeyw 'Creator',136
- mkeyw 'Account',137
- mkeyw 'Area',138
- mkeyw 'Block-size',139
- mkeyw 'Access',140
- mkeyw 'Encoding',141
- mkeyw 'Disposition',142
- mkeyw 'Protection',143
- mkeyw 'Gprotection',144
- mkeyw 'System-ID',145
- mkeyw 'Format',146
- mkeyw 'Sys-Info',147
- mkeyw 'Byte-count',148
-
- remsfit db 5 ; REMOTE SET FILE
- mkeyw 'Type',300
- mkeyw 'Names',301
- mkeyw 'Collision',302
- mkeyw 'Replace',303
- mkeyw 'Incomplete',310
-
- remsfty db 2 ; REMOTE SET FILE TYPE
- mkeyw 'Text',0
- mkeyw 'Binary',1
-
- remsfna db 2 ; REMOTE SET FILE NAME
- mkeyw 'Converted',0
- mkeyw 'Literal',1
-
- remsfco db 7 ; REMOTE SET FILE COLLISION
- mkeyw 'Append',3
- mkeyw 'Ask',5
- mkeyw 'Backup',2
- mkeyw 'Discard',4
- mkeyw 'Rename',0
- mkeyw 'Replace',1
- mkeyw 'Update',6
-
- remsfre db 2 ; REMOTE SET FILE REPLACE
- mkeyw 'Preserve',0
- mkeyw 'Default',1
-
- remsfin db 2 ; REMOTE SET FILE INCOMPLETE
- mkeyw 'Discard',0
- mkeyw 'Keep',1
-
- remsrcv db 2 ; REMOTE SET RECEIVE
- mkeyw 'Packet-length',401
- mkeyw 'Timeout',402
-
- remsxfr db 1 ; REMOTE SET TRANSFER
- mkeyw 'Character-set',405
-
-
- onoff db 2 ; ON, OFF table
- mkeyw 'off',0
- mkeyw 'on',1
-
- data ends
-
- code1 segment
- extrn bufclr:far, pakptr:far, bufrel:far, makebuf:far, chkwind:far
- extrn firstfree:far, getbuf:far, pakdup:far, rpack:far, fcsrtype:far
- code1 ends
-
- code segment
- extrn comnd:near, init:near, serini:near, rrinit:near
- extrn read2:near, rpar:near, spar:near, intmsg:near, sparmax:near
- extrn serhng:near, clrbuf:near, clearl:near
- extrn dodec: near, doenc:near, packlen:near, send10:near, errpack:near
- extrn pktsize:near, poscur:near, lnout:near, clrmod:near, ermsg:near
- extrn rprpos:near, crun:near, prompt:near, prtscr:near, strcat:near
- extrn strlen:near, strcpy:near, fparse:near, isfile:near, ihostr:near
- extrn inptim:near, chktmo:near, pcwait:near
- extrn nakpak:near, sndpak:near, response:near
- extrn msgmsg:near, ackpak:near, dskspace:near, cdsr:near, dec2di:near
- extrn takopen:near, takclos:near, setcom:near
- extrn remprn:near
-
- assume cs:code, ds:data, es:nothing
-
- ; Server command
-
- SERVER PROC NEAR
- mov ah,cmword ; get a word
- mov dx,offset srvbuf ; place to put text
- mov word ptr srvbuf,0 ; clear
- mov bx,offset inthlp ; help message
- call comnd ; get the pattern text
- jnc serv1a ; nc = success
- ret ; failure
- serv1a: mov ah,cmeol
- call comnd
- jnc serv1b ; nc = success
- ret
- serv1b: mov srvtime,0 ; assume not doing timed residence
- mov si,offset srvbuf
- mov al,[si]
- or al,al ; any time given?
- jz serv4 ; z = no
- cmp al,'0' ; numeric or colon?
- jb serv2 ; b = not proper time value
- cmp al,':' ; this covers the desired range
- ja serv2 ; a = no proper time value
- call inptim ; convert text to timeout tod
- jnc serv3 ; c = syntax errors in time
- serv2: stc ; failure
- ret
-
- serv3: mov srvtime,1 ; say doing timed residence
- serv4: or flags.remflg,dserver ; signify we are a server now
- call clrbuf ; clear serial port buffer of junk
- test denyflg,pasflg ; Login required?
- jnz serv4a ; nz = no
- or denyflg,pasflg ; assume no login info required
- mov al,luser ; check for user/password required
- or al,lpass ; if both null then no checks
- jz serv4a ; z = null, no name/pass required
- and denyflg,not pasflg ; say need name/password
- serv4a: mov dsptmp,0 ; assume no formatted server display
- mov al,dtrans.xchset ; reset Transmission char set
- mov trans.xchset,al ; to the current user default
- mov al,dtrans.xtype ; ditto for File Type
- mov trans.xtype,al
- mov si,offset flags ; main flags structure
- mov di,offset savflg ; save area
- mov cx,savflgl ; length in bytes
- push es
- push ds
- pop es
- cld
- rep movsb ; save all of them
- mov si,offset dtrans ; default transmission parameters
- mov di,offset savdtr ; save area
- mov cx,savdtrl ; length
- rep movsb ; save all of them
- mov si,offset trans ; active transmission paramters
- mov di,offset savtr ; save area
- mov cx,savdtrl ; same length
- rep movsb
- mov al,maxtry
- mov savmaxtry,al
- pop es
- mov si,offset rpacket ; dummy packet
- mov rpacket.datlen,0 ; declare to be empty
- call spar ; setup minimum operating conditions
- test flags.remflg,dquiet ; quiet display?
- jnz serv9 ; nz = yes
- mov ah,prstr
- mov dx,offset crlf
- int dos
- test flags.remflg,dserial ; serial display?
- jnz serv5 ; nz = yes
- call init ; init formatted display
- call clrmod ; but no modeline yet
- mov dl,fmtdsp
- mov dsptmp,dl ; remember state of fmtdsp
- jmp short serv9
-
- serv5: mov ah,prstr
- mov dx,offset infms1 ; say now in server mode
- int dos
-
- ; TOP OF SERVER IDLE LOOP
- serv9: test flags.remflg,dquiet+dserial ; quiet or serial display?
- jnz serv10 ; nz = yes, do not change screen
- mov dx,scrmsg ; move cursor to Last message area
- add dx,0100H ; look at line below (DOS does CR/LF first)
- call poscur
- call clearl ; and clear the line
- mov dl,cr ; set cursor to left margin
- mov ah,conout
- int dos
- serv10: xor ax,ax
- mov flags.cxzflg,al ; clear ^X, ^Z, ^C seen flag
- mov flags.xflg,al ; reset X packet flag
- mov auxfile,al ; say no override filename
- mov srvbuf,al ; work buffer, clear
- mov al,dsptmp ; get our fmtdsp state
- mov fmtdsp,al ; and restore it
- mov trans.windo,1 ; but only 1 window slot here
- mov cx,drpsiz ; default receive pkt length (94)
- call makebuf ; remake all buffers for new windowing
- call packlen ; determine max packet length
- mov dtrans.windo,31 ; set max windowing abilities
- mov trans.windo,31
- mov trans.chklen,1 ; checksum len = 1
- mov pktnum,0 ; pack number resets to 0
- mov al,srvtmo ; use server mode timeout
- or al,al ; is it zero?
- jz serv10b ; z = yes, use regular timeout
- mov trans.stime,al ; use this interval in the idle loop
- serv10b:call serini ; init serial line, just in case
- jnc serv11 ; nc = success
- jmp serv20 ; c = failure
- serv11: cmp srvtime,0 ; doing timed residence?
- je serv12 ; e = no
- call chktmo ; check for time to exit Server mode
- jnc serv12 ; nc = ok
- jmp serv20 ; c = timeout, exit server mode
-
- serv12: mov windlow,0 ; reset windowing
- mov pktnum,0 ; packet number to be used
- call getbuf ; get a buffer
- mov chkparflg,1 ; check for unexpected parity
- call rpack ; receive a packet, si has buffer ptr
- mov al,dtrans.stime ; get default timeout interval
- mov trans.stime,al ; restore active timeout interval
- jc serv13 ; c = timeout, bad pkt, intervention
- mov al,[si].seqnum ; sequence number received
- mov rpacket.seqnum,al ; for our reply
- or al,al ; must be sequence number of zero
- jnz serv13 ; nz = bad packet
- mov ah,[si].pktype
- cmp ah,'I' ; never "decode" S, I, and A packets
- je serv17 ; e = I packet
- cmp ah,'S'
- je serv17
- cmp ah,'A'
- je serv17
- call dodec ; decode packet to decbuf
- call bufrel ; release the packet buffer
- jmp short serv17 ; dispatch on packet type in ah
-
- serv13: cmp flags.cxzflg,'C' ; Control-C?
- je serv20 ; e = yes, exit server mode
-
- serv14: cmp flags.cxzflg,'E' ; ^E protocol abort?
- jne serv15 ; ne = no
- call bufclr ; clear all buffers
- mov dx,offset cemsg ; user intervention message for error packet
- call ermsg
- mov bx,dx
- call errpack ; send error message
- call intmsg ; show interrupt msg for Control-C-E
- jmp serv9
-
- serv15: cmp [si].pktype,'T' ; packet type of time-out?
- jne serv16 ; ne = no
- cmp srvtime,0 ; doing timed residence?
- je serv15a ; e = no
- call chktmo ; check for time to exit Server mode
- jc serv20 ; c = timeout, exit server mode
- serv15a:cmp srvtmo,0 ; zero server pkt timeout?
- je serv16 ; e = yes, no NAKing
- mov rpacket.seqnum,0
- call nakpak ; NAK the packet, uses rpacket
- serv16: call bufrel ; release the buffer
- jmp serv9 ; to top of idle loop
-
- serv17: cmp [si].pktype,'N' ; received a NAK?
- je serv18 ; e = yes, ignore it
- push es
- push ds
- pop es ; set es to data segment
- mov di,offset srvchr ; server characters
- mov cx,srvfln ; length of command set
- mov al,ah ; packet type
- cld
- repne scasb ; hunt for it
- pop es
- je serv19 ; e = found that kind
- mov dx,offset remms1 ; say unknown server command
- call ermsg
- mov bx,dx
- call errpack ; tell the other kermit
- serv18: jmp serv9 ; get another server command
-
- serv19: sub di,offset srvchr+1 ; find offset, +1 for pre-increment
- shl di,1 ; convert to word index
- call srvfun[di] ; call the appropriate handler
- jc serv20 ; c = someone wanted to exit
- jmp serv9 ; get another server command
-
- serv20: mov di,offset flags ; main flags structure
- mov si,offset savflg ; save area
- mov cx,savflgl ; length in bytes
- push es
- push ds
- pop es
- mov al,flags.extflg ; leave server mode and Kermit flag
- mov ah,flags.cxzflg ; interruption flag
- cld
- rep movsb ; restore all of them
- mov di,offset dtrans ; default transmission parameters
- mov si,offset savdtr ; save area
- mov cx,savdtrl ; length
- rep movsb ; restore all of them
- mov di,offset trans ; active transmission paramters
- mov si,offset savtr ; save area
- mov cx,savdtrl ; same length
- rep movsb
- mov flags.extflg,al ; set flag as current
- ;; mov flags.cxzflg,ah ; restore interruption flag
- mov al,savmaxtry
- mov maxtry,al
- pop es
- mov al,1 ; underline cursor
- call fcsrtype ; set IBM-PC cursor to underline
- call rprpos ; put prompt here
- and flags.remflg,not dserver ; say not a server anymore
- clc
- ret
- SERVER ENDP
-
- ; commands executable while acting as a server
-
- ; Validate LOGIN status. Return carry set if login is ok, else
- ; send Error Packet saying Login is required (but has not been done) and
- ; return carry clear. Carry bit is this way because returning to the server
- ; idle loop with carry set exits the server mode.
- logchk proc near
- test denyflg,pasflg ; login required?
- jnz logchk1 ; nz = no (disabled)
- cmp slogin,0 ; logged in yet?
- jne logchk1 ; ne = yes
- mov dx,offset remms7 ; reply REMOTE LOGIN is required
- call ermsg
- mov bx,dx ; errpack works from bx
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack
- clc ; say cannot proceed with command
- ret
- logchk1:stc ; say can proceed with command
- ret
- logchk endp
-
- ; srvsnd - receives a file that a remote kermit is sending
- srvsnd proc near
- call logchk ; check login status
- jc srvsnd1 ; c = ok
- ret ; else have sent error packet
- srvsnd1:call init ; setup display form
- xor ax,ax
- test denyflg,sndflg ; command disabled?
- jz srvsnd2 ; z = no
- mov al,'.' ; dot+nul forces use of current dir
- srvsnd2:mov word ptr auxfile,ax ; override name
- mov rstate,'R' ; receive initiate state
- jmp read2 ; packet pointer is SI, still valid
- srvsnd endp
-
- ; srvrcv - send a file to a distant kermit
-
- srvrcv proc near
- call logchk ; check login status
- jc srrcv1 ; c = ok
- ret ; else have sent error packet
- srrcv1: mov si,offset decbuf ; received filename, asciiz from dodec
- test denyflg,getsflg ; command enabled?
- jz srrcv2 ; z = yes
- mov dx,si ; source string, from other side
- mov di,offset srvbuf ; local path
- mov si,offset tmpbuf ; local filename
- call fparse ; split string
- srrcv2: mov di,offset diskio.string ; destination
- call strcpy ; copy filename to diskio.string
- mov auxfile,0 ; no alias name
- mov sstate,'S' ; set sending state
- jmp send10 ; this should send it
- srvrcv endp
-
- srverr proc near ; incoming Error packet
- clc ; absorb and ignore
- ret
- srverr endp
-
- ; srvgen - G generic server command dispatcher
- ;
- srvgen proc near
- call bufrel ; release buffer
- mov al,decbuf ; get first data character from pkt
- cmp al,'I' ; LOGIN?
- jne srvge1 ; ne = no
- jmp srvlogin ; yes
- srvge1: call logchk ; check login status
- jc srvge2 ; c = ok
- ret ; else have sent error packet
- srvge2: push es
- push ds
- pop es ; set es to data segment
- mov di,offset srvch2 ; command character list
- mov cx,srvfl2 ; length of command set
- cld
- repne scasb ; hunt for it
- pop es
- jne srvgex ; ne = not found, complain
- sub di,offset srvch2+1 ; find offset, +1 for pre-increment
- shl di,1 ; convert to word index
- jmp srvdsp[di] ; do the appropriate handler
-
- srvgex: mov dx,offset remms1 ; reply Unknown server command
- call ermsg
- mov bx,dx
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack
- clc
- ret
- srvgen endp
-
- ; srvlog - respond to host's BYE and LOGOUT
- srvlog proc near
- call srvfin ; do FIN part
- pushf ; save flag for the very end
- jnc srvlog1 ; nc = stay active (command denied)
- mov flags.extflg,1 ; leave server mode and Kermit
- srvlog1:call serhng ; hangup the phone and return
- mov di,offset flags ; main flags structure
- mov si,offset savflg ; save area
- mov cx,savflgl ; length in bytes
- push es
- push ds
- pop es
- mov al,flags.extflg ; leave server mode and Kermit flag
- cld
- rep movsb ; restore all of them
- mov di,offset dtrans ; default transmission parameters
- mov si,offset savdtr ; save area
- mov cx,savdtrl ; length
- rep movsb ; restore all of them
- mov di,offset trans ; active transmission paramters
- mov si,offset savtr ; save area
- mov cx,savdtrl ; same length
- rep movsb
- mov flags.extflg,al ; make flag current
- mov al,savmaxtry
- mov maxtry,al
- pop es
- popf ; recover carry flag, set = exit
- ret
- srvlog endp
-
- ; srvfin - respond to remote host's Fin command
- srvfin proc near
- mov slogin,0 ; say not logged in anymore
- mov si,offset byemsg ; add brief msg of goodbye
- mov di,offset encbuf ; packet's data field
- call strcpy ; copy msg to pkt
- mov dx,si ; strlen works on dx
- call strlen
- push si
- mov si,offset rpacket ; get a reply buffer
- call doenc ; encode the reply in encbuf
- pop si
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- mov ax,100 ; wait 0.1 sec for client to settle
- call pcwait
- mov si,offset rpacket ; dummy packet
- mov rpacket.datlen,0 ; declare to be empty
- call spar ; setup minimum operating conditions
- test denyflg,finflg ; command enabled?
- jz srfin2 ; z = yes
- clc ; stay in server mode
- ret
- srfin2: stc ; stc exits server mode
- ret
- srvfin endp
-
- ; srvcwd - handle other side's Remote CWD dirspec
- srvcwd proc near
- mov trans.chklen,1 ; reply with 1 char checksum
- test denyflg,cwdflg ; is command enabled?
- jz srcwd1 ; z = yes
- mov dx,offset remms9 ; say command is disabled
- call ermsg ; to us and
- mov bx,dx
- call errpack ; to the other Kermit
- clc
- ret
- srcwd1: mov si,offset decbuf+1 ; point to byte count
- xor bh,bh
- mov bl,[si]
- sub bl,' ' ; remove ascii bias from byte count
- inc si
- mov word ptr[si+bx],0 ; make ASCIIZ w/one extra null
- call cdsr ; CD common sub-routine
- mov si,dx ; returns msg in dx
- mov di,offset encbuf ; put in encode buffer
- call strcpy
- mov dx,di
- call strlen ; get its length to cx
- mov si,offset rpacket ; use this packet for the reply
- call doenc ; encode reply
- call ackpak ; send ACK with data
- clc
- ret
- srvcwd endp
-
- ; srvtyp - handle other side's Remote Type filename request
- ; expects "data" to hold Tcfilename where c = # bytes in filename
- srvtyp proc near
- cmp decbuf+1,0 ; any data in packet
- je srtyp2 ; e = no
- mov cl,decbuf+1 ; get the filename byte count
- sub cl,' ' ; ascii to numeric
- jle srtyp2 ; le = no filename or error in length
- xor ch,ch ; set up counter
- mov si,offset decbuf+2 ; received filename, asciiz from rpack
- mov di,si
- add di,cx
- mov byte ptr [di],0 ; make string asciiz
- test denyflg,typflg ; paths permitted?
- jz srtyp1 ; z = yes, else use just filename part
- mov di,offset srvbuf ; local path
- mov si,offset tmpbuf ; local filename
- mov dx,offset decbuf+2 ; local string
- call fparse ; split string
- srtyp1: mov di,offset diskio.string ; copy local filename to destination
- mov ax,di ; pointer to filename, for isfile
- call strcpy ; do the copy
- call isfile ; does it exist?
- jnc srtyp3 ; nc = yes
- srtyp2: mov si,offset remms5 ; "File not found"
- mov di,offset encbuf ; destination for message
- call strcpy ; move the message
- mov dx,di
- call strlen ; length to cx
- mov si,offset rpacket ; use this packet for reply
- call doenc ; encode
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak ; send ACK with message
- clc
- ret
-
- srtyp3: mov flags.xflg,1 ; say use X packet rather than F pkt
- mov auxfile,0 ; no alias name
- mov sstate,'S' ; remember state
- jmp send10 ; this should send it
- srvtyp endp
-
- ; srvdir - handle other side's Remote Dir filespec(optional) request
- srvdir proc near
- mov di,offset decbuf+2 ; received filespec, asciiz from rpack
- xor cx,cx ; assume no data in packet
- mov cl,decbuf+1 ; get the filename byte count
- cmp cl,' ' ; byte count present and > 0?
- jg srdir1 ; g = yes
- mov word ptr [di],0 ; clear data field
- jmp short srdir2 ; 0 = no info in pkt
- srdir1: sub cl,' ' ; ascii to numeric
- add di,cx ; step to end of filename, terminate
- mov word ptr [di],0 ; ensure string is asciiz
- mov di,offset srvbuf ; local path
- mov si,offset tmpbuf ; local filename
- mov dx,offset decbuf+2 ; local string
- call fparse ; split string
- test denyflg,dirflg ; paths permitted?
- jz srdir2 ; z = yes, else use just filename part
- mov si,offset tmpbuf ; copy local filename to
- mov di,offset decbuf+2 ; final filename
- call strcpy ; copy just filename to buffer
- srdir2: mov cl,curdsk ; current drive number
- add cl,'A'-1 ; to letter
- cmp decbuf+3,':' ; drive specified?
- jne srdir3 ; ne = no
- cmp decbuf+2,0 ; drive letter specified?
- je srdir3 ; e = no
- mov cl,decbuf+2 ; get drive letter
- and cl,5fh ; convert to upper case
- srdir3: call dskspace ; check if drive ready (drive => CL)
- jnc srdir5 ; nc = success (drive is ready)
- mov spcmsg3,cl ; insert drive letter
- mov si,offset spcmsg2 ; say drive not ready
- mov di,offset encbuf ; destination for message
- call strcpy ; move the message
- mov dx,di
- call strlen ; length to cx
- mov si,offset rpacket ; use this packet for reply
- call doenc ; encode
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak ; send ACK with message
- clc
- ret
-
- srdir5: mov di,offset srvbuf ; work area
- mov si,offset dirstr ; prepend "dir "
- call strcpy
- mov si,offset decbuf+2 ; directory spec, asciiz
- mov di,offset srvbuf
- call strcat
-
- ; srdir6 does common processing for both REM DIR & REM HOST
- SRDIR6: mov si,di ; srvbuf
- mov di,offset auxfile ; send-as name is command line
- call strcpy
- mov dl,curdsk
- add dl,'A'-1 ; change to letter
- mov srvtmp+2,dl ; insert current disk drive
- mov si,offset srvtmp ; add redirection tag " >d:$kermit$.tmp"
- mov di,offset srvbuf
- call strcat
- mov si,offset srvbuf ; command pointer for crun
- call crun
- ; fall thru! jmp srvtail ; send contents of temp file
- srvdir endp
-
- ; Send contents of srvtmp+2 temporary file, or error packet if it does not
- ; exist.
- srvtail proc near
- mov si,offset srvtmp+2 ; get name of temp file
- mov di,offset diskio.string ; destination
- call strcpy ; copy it there
- mov ax,di ; filename pointer for isfile
- call isfile ; did we make the temp file?
- jnc srvtai1 ; nc = yes
- mov dx,offset remms10 ; "Could not create work file"
- mov trans.chklen,1 ; reply with 1 char checksum
- call ermsg
- mov bx,dx
- call errpack ; send the error message
- clc
- ret
- srvtai1:mov flags.xflg,1 ; say use X rather than F packet
- mov sstate,'S' ; remember state
- call send10 ; this should send it
- mov flags.xflg,0 ; clear flag
- mov dx,offset srvtmp+2 ; name of temp file
- mov ah,del2 ; delete the file
- int dos
- clc
- ret ; return in any case
- srvtail endp
-
- ; srvdel - handle other side's request of Remote Del filespec
- srvdel proc near
- test denyflg,delflg ; command enabled?
- jz srvdel4 ; z = yes
- mov dx,offset remms9 ; else give a message
- mov trans.chklen,1 ; reply with 1 char checksum
- call ermsg
- mov bx,dx
- call errpack ; back to local kermit
- clc
- ret
-
- srvdel4:cmp decbuf+1,0 ; any data?
- je srdel1 ; e = no
- xor bh,bh
- mov bl,decbuf+1 ; get the filename byte count
- sub bl,' ' ; ascii to numeric
- jle srdel3 ; le = nothing there
- mov decbuf [bx+2],0 ; plant terminator
- mov ax,offset decbuf+2 ; point to filespec
- call isfile ; is/are there any to delete?
- jc srdel1 ; c = there is none
- test byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
- jz srdel2 ; z = not protected
- srdel1: mov si,offset remms5 ; "File not found"
- mov di,offset encbuf ; destination for message
- call strcpy ; move the message
- mov dx,di
- call strlen ; length to cx
- mov si,offset rpacket ; use this packet for reply
- call doenc ; encode
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak ; send ACK with message
- clc
- ret
-
- srdel2: mov di,offset encbuf ; work area
- mov si,offset delstr ; prepend "del "
- call strcpy
- mov si,offset decbuf+2 ; append incoming filespec
- call strcat ; append to "del "
- mov si,di ; set pointer for crun
- call crun
- srdel3: mov dx,offset encbuf ; where command lies
- call strlen ; length to cx
- push si
- mov si,offset rpacket ; packet to use for reply
- call doenc ; encode reply
- pop si
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- clc
- ret
- srvdel endp
-
- ; srvlogin - handle other side's request of REMOTE LOGIN, USERNAME, PASSWORD
-
- srvlogin proc near
- mov slogin,0 ; say not logged in yet
- cmp luser,0 ; local username specified?
- je srvlog9 ; e = no, do no checking
- mov cl,decbuf+1 ; ascii byte count of username
- sub cl,' ' ; to binary
- jle srvlog8 ; le = nothing there
- xor ch,ch
- mov si,offset decbuf+2 ; source, username field
- mov di,offset luser ; local username template
- push cx
- mov ax,cx ; external username length
- mov dx,di
- call strlen ; get length of local username
- cmp ax,cx ; same lengths?
- pop cx
- jne srvlog8 ; ne = not same length
- cld
- srvlog2:lodsb ; remote char
- mov ah,[di] ; local char
- inc di
- or ax,2020h ; lower case both
- cmp ah,al ; same?
- jne srvlog8 ; ne = no, fail
- loop srvlog2 ; continue match
- cmp lpass,0 ; local password specified?
- je srclog6 ; e = no, don't check incoming p/w
- mov cl,decbuf+1 ; username length
- sub cl,' '
- xor ch,ch ; clear high byte
- mov si,offset decbuf+2 ; skip over username field
- add si,cx ; password length byte
- mov cl,[si] ; ascii count of password bytes
- sub cl,' ' ; to binary
- jc srvlog8 ; carry means no field
- inc si ; start of password text
- mov di,offset lpass ; local password text, case sensitive
- push cx
- mov ax,cx ; external password length
- mov dx,di
- call strlen ; length of local password
- cmp ax,cx ; same?
- pop cx
- je srvlog5 ; e = yes
- mov byte ptr [si],20h ; corrupt external password
- jmp short srvlog8 ; fail
- srvlog5:lodsb ; remote char
- mov ah,[di] ; local char
- inc di
- cmp ah,al ; same?
- jne srvlog8 ; ne = no, fail
- loop srvlog5 ; do all chars
- srclog6:mov slogin,1 ; declare user logged-in
- jmp short srvlog9 ; ACK with brief message
-
- srvlog8:mov si,offset remms2 ; say invalid login information
- jmp short srvlog10
-
- srvlog9:mov si,offset remms3 ; welcome aboard message
- mov slogin,1 ; say logged in successfully
- srvlog10:mov di,offset encbuf ; copy to here
- call strcpy
- mov dx,di ; where command lies
- call strlen ; length to cx
- push si
- mov si,offset rpacket ; packet to use for reply
- call doenc ; encode reply
- pop si
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- clc
- ret
- srvlogin endp
-
- ; srvspc - handle other side's request of Remote Space
- srvspc proc near
- test denyflg,spcflg ; is command enabled?
- jz srspc1 ; z = yes
- mov dx,offset remms9 ; else give a message
- mov trans.chklen,1 ; reply with 1 char checksum
- call ermsg
- mov bx,dx
- call errpack ; back to local kermit
- clc
- ret
- srspc1: xor cl,cl ; use current drive
- cmp decbuf+1,0 ; any data?
- je srspc2 ; e = no
- mov cl,decbuf+2 ; get the drive letter
- srspc2: call dskspace ; calculate space, get letter into CL
- jnc srspc3 ; nc = success
- mov spcmsg3,cl ; insert drive letter
- mov di,offset encbuf ; encoder buffer
- mov si,offset spcmsg2 ; give Drive not ready message
- call strcpy
- jmp short srspc4 ; send it
- srspc3: mov spcmsg1,cl ; insert drive letter
- mov di,offset encbuf ; destination
- mov word ptr[di],' ' ; space space
- add di,2 ; start number here
- call lnout ; convert number to asciiz in [di]
- mov si,offset spcmsg ; trailer of message
- call strcat ; tack onto end of number part
- srspc4: mov trans.chklen,1 ; reply with 1 char checksum
- mov dx,offset encbuf
- call strlen ; get data size into cx for doenc
- mov si,offset rpacket
- call doenc ; encode
- call pktsize ; report packet size
- call ackpak
- clc
- ret
- srvspc endp
-
- ; srvwho - respond to remote host's WHO command.
- srvwho proc near
- mov si,offset whomsg ; add brief msg of just us chickens
- mov di,offset encbuf ; encoder source field
- call strcpy ; copy msg to pkt
- mov dx,si ; strlen works on dx
- call strlen
- mov si,offset rpacket
- call doenc ; encode reply, size is in cx
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- clc
- ret
- srvwho endp
-
- ; srvmsg - respond to remote host's Message (Send) command
- ; show message on our screen.
- srvmsg proc near
- cmp decbuf,0 ; any data in the packet?
- jbe srvmsg2 ; e = no, just ack the message
- cmp decbuf,'M' ; Message packet?
- jne srvmsg2 ; ne = no, ack and forget
- test flags.remflg,dquiet+dserial ; quiet or serial display?
- jnz srvmsg1 ; nz = yes
- mov dx,scrmsg ; move cursor to Last message area
- call poscur
- call clearl ; and clear the line
- srvmsg1:xor ch,ch
- mov cl,decbuf+1 ; data length
- sub cl,' ' ; remove ascii bias
- jle srvmsg2 ; le = nothing
- mov di,offset decbuf+2 ; main part of message
- call prtscr ; display cx chars on the screen
- srvmsg2:mov rpacket.datlen,0 ; length
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- clc
- ret
- srvmsg endp
-
-
- ; srvhos - handle other side's request of REM Host command-line. [jrd]
- ; We execute the command with STDOUT redirected to $kermit$.tmp and then
- ; read and transmit that file to the other end. No such file results in
- ; returning just an error msg ACK packet
- srvhos proc near
- call logchk ; check login status
- jc srvhos1 ; c = ok
- ret ; else have sent error packet
- srvhos1:test denyflg,hostflg ; command enabled?
- jz srvhos2 ; z = yes
- mov trans.chklen,1 ; reply with 1 char checksum
- mov dx,offset remms9 ; else give a message
- call ermsg
- mov bx,dx
- call errpack ; back to local kermit
- clc
- ret
-
- srvhos2:mov si,offset decbuf ; received filename, asciiz from dodec
- mov di,offset srvbuf ; destination
- call strcpy ; copy data to srvbuf
- jmp SRDIR6 ; do common completion code
- srvhos endp
-
- ; Respond to other side's request of Remote Help. Write & read $kermit$.tmp
- srvhlp proc near
- mov dl,curdsk
- add dl,'A'-1 ; change to letter
- mov srvtmp+2,dl ; insert current disk drive
- mov dx,offset srvtmp+2 ; use filename of d:$kermit$.tmp
- mov ah,creat2 ; create the file
- xor cx,cx ; attributes r/w
- int dos
- jc srvhlp1 ; c = could not open
- mov dx,offset hlprem ; data to be sent, strlen uses dx
- call strlen ; put string length in cx
- mov bx,ax ; handle
- mov ah,write2 ; write to file
- int dos ; write the info
- mov ah,close2 ; close the file so we can reread it below
- int dos
- srvhlp1:mov si,offset infms4 ; pseudo filename
- mov di,offset auxfile ; send-as name
- call strcpy ; copy it there
- jmp srvtail ; send temporary file to remote screen
- srvhlp endp
-
- ; srvker - handle other side's request of REM Kermit command-line.
- srvker proc near
- call logchk ; check login status
- jc srvker8 ; c = ok
- ret ; else have sent error packet
- srvker8:test denyflg,kerflg ; command enabled?
- jz srvker1 ; z = yes
- mov trans.chklen,1 ; reply with 1 char checksum
- mov dx,offset remms9 ; else give a message
- call ermsg
- mov bx,dx
- call errpack ; back to local kermit
- clc
- ret
-
- srvker1:call takopen ; open a Take file
- jc srvker3 ; c = failed to obtain Take space
- mov dx,prmptr ; get prompt
- call prompt ; prompt user, set reparse address
- mov bx,takadr ; pointer to Take structure
- mov skertmp,bx ; remember it here for cleanup
- mov [bx].taktyp,0ffh ; mark as a macro
- mov dx,offset decbuf ; received command, asciiz
- call strlen ; get length into cx
- mov si,dx
- srvker6:cmp byte ptr [si],' ' ; strip leading white space
- ja srvker7 ; a = non-white
- loop srvker6 ; continue
- srvker7:cmp cx,8 ; need at least 8 chars "SET xx y"
- jb srvker2 ; b = too few, bad command
- mov ax,[si] ; get first two characters
- or ax,2020h ; lower case them
- cmp ax,'es' ; start of "SET"?
- jne srvker2 ; ne = no, bad command
- mov ax,[si+2] ; next two
- or ax,2020h
- cmp ax,' t' ; rest of "SET "?
- jne srvker2 ; ne = no, bad command
- add si,4 ; move to end of "SET "
- sub cx,4
- mov [bx].takcnt,cx ; number of bytes in command
- push es
- mov ax,[bx].takbuf ; segment of Take buffer
- mov es,ax
- mov di,1 ; place here (skip buf length byte)
- cld
- rep movsb
- pop es
- call setcom
- jnc srvker3 ; nc = success
- srvker2:mov si,offset remms6 ; "Command failed"
- jmp short srvker4
- srvker3:mov si,offset remms8 ; "Command succeeded"
- srvker4:mov di,offset encbuf ; destination for message
- call strcpy ; move the message
- mov dx,di
- call strlen ; length to cx
- mov si,offset rpacket ; use this packet for reply
- call doenc ; encode
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak ; send ACK with message
- mov ax,skertmp ; get old take address
- cmp ax,takadr ; same (still in current Take)?
- jne srvker5 ; ne = no
- call takclos ; close the Take file
- srvker5:clc
- ret
- srvker endp
-
- ; Command Code Values
- ; REMOTE SET ATTRIBUTES IN ALL 132 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES IN LENGTH 133 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES IN TYPE 134 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES IN DATE 135 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN CREATOR 136 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN ACCOUNT 137 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN AREA 138 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN BLOCK-SIZE 139 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN ACCESS 140 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN ENCODING 141 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN DISPOSITION 142 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN PROTECTION 143 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN GPROTECTION 144 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN SYSTEM-ID 145 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN FORMAT 146 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN SYS-INFO 147 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES IN BYTE-COUNT 148 0 = OFF, 1 = ON
- ;
- ; REMOTE SET ATTRIBUTES OUT ALL 232 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES OUT LENGTH 233 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES OUT TYPE 234 0 = OFF, 1 = ON
- ; REMOTE SET ATTRIBUTES OUT DATE 235 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT CREATOR 236 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT ACCOUNT 237 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT AREA 238 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT BLOCK-SIZE 239 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT ACCESS 240 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT ENCODING 241 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT DISPOSITION 242 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT PROTECTION 243 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT GPROTECTION 244 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT SYSTEM-ID 245 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT FORMAT 246 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT SYS-INFO 247 0 = OFF, 1 = ON
- ;X REMOTE SET ATTRIBUTES OUT BYTE-COUNT 248 0 = OFF, 1 = ON
- ;
- ; REMOTE SET FILE TYPE 300 0 = TEXT, 1 = BINARY
- ;X REMOTE SET FILE NAMES 301 0 = CONVERTED, 1 = LITERAL
- ; REMOTE SET FILE COLLISION 302 0 = RENAME, 1 = REPLACE,
- ; X 2 = BACKUP, X 3 = APPEND,
- ; 4 = DISCARD, X 5 = ASK
- ;X REMOTE SET FILE REPLACE 303 0 = PRESERVE, 1 = DEFAULT
- ; REMOTE SET INCOMPLETE 310 0 = DISCARD, 1 = KEEP
- ;
- ; REMOTE SET BLOCK-CHECK 400 number (1, 2, or 3)
- ; REMOTE SET RECEIVE PACKET-LENGTH 401 number (10-9024)
- ; REMOTE SET RECEIVE TIMEOUT 402 number (any, 0 = no timeout)
- ; REMOTE SET RETRY 403 number (any, 0 = no limit)
- ; REMOTE SET SERVER TIMEOUT 404 number (any, 0 = no timeout)
- ; REMOTE SET TRANSFER CHARACTER-SET 405 Character Set Designator
- ; REMOTE SET WINDOW-SLOTS 406 number (1-31)
- ;
- ; Items marked with "X" are ignored by this server
-
- ; srvset - manage incoming REMOTE SET commands
- ; decode buffer looks like S<len1><value1><len2><value2>
- srvset proc near
- mov bufptr,offset decbuf+1 ; received command data, asciiz
- call srvswk ; worker to convert first value to ax
- jc srvset3 ; c = failure
- mov temp,ax ; save first value here
- cmp ax,132 ; before known set?
- jb srvset3 ; b = yes, bad
- mov di,offset sattr ; assume SET ATTRIBUTES
- cmp ax,148 ; still in range?
- jbe srvset2 ; be = yes
- cmp ax,232 ; before next range?
- jb srvset1 ; b = yes
- cmp ax,248 ; still in range?
- jbe srvset2 ; be = yes, get final value
- srvset1:push es ; do table lookup on other values
- push ds
- pop es
- mov di,offset setval ; look up other codes in table
- mov cx,setvlen
- cld
- repne scasw
- pop es
- mov bx,offset remms1 ; "Unknown server command", if needed
- jne srvset3 ; ne = no match, unknown command
- sub di,offset setval+2 ; get displacement
- mov di,setvec[di]
- srvset2:call di ; call the action routine
- mov bx,offset remms6 ; "Command failed", if needed
- jc srvset3 ; c = failure
- mov si,offset remms8 ; "Command succeeded"
- mov di,offset encbuf ; destination for message
- call strcpy ; move the message
- mov dx,di
- call strlen ; length to cx
- mov si,offset rpacket ; use this packet for reply
- call doenc ; encode
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak ; send ACK with message
- clc
- ret
- srvset3:mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send error message in ptr bx
- clc
- ret
- srvset endp
-
- sattr proc near ; SET ATTRIBUTES IN/OUT ITEM ON/OFF
- mov ax,temp ; get kind of attribute
- cmp ax,200 ; the OUT kind?
- jb sattr1 ; b = no, IN kind
- sub ax,100 ; merge to same thing
- sattr1: cmp ax,132 ; ALL?
- jne sattr2 ; be = ok
- mov bl,0ffh ; all bits
- jmp short sattr6
- sattr2: cmp al,133 ; Length?
- jne sattr3 ; ne = no
- mov bl,attlen
- jmp short sattr6
- sattr3: cmp al,134 ; Type
- jne sattr4 ; ne = no
- mov bl,atttype
- jmp short sattr6
- sattr4: cmp bl,135 ; Date?
- jne sattr5 ; ne = no, fail
- mov bl,attdate
- jmp short sattr6
- sattr5: stc ; fail
- ret
- sattr6: call srvswk ; get second value to ax, 1 = on
- jc sattr5 ; c = failure
- or ax,ax ; off?
- jnz sattr7 ; nz = no, on
- mov al,flags.attflg ; current flags
- not bl ; invert selected items
- and al,bl ; turn off selected items
- mov flags.attflg,al ; store the flags
- clc
- ret
- sattr7: cmp ax,1 ; on?
- jne sattr5 ; ne = no, fail
- or flags.attflg,bl ; insert ON selected bits
- clc
- ret
- sattr endp
-
- sftype proc near ; SET FILE TYPE
- call srvswk ; get second value to ax
- jc sftypb ; c = failure
- cmp al,1
- ja sftypb ; a = bad
- mov trans.xtype,al ; store transfer type
- mov dtrans.xtype,al ; store transfer type
- clc
- ret
- sftypb: stc ; bad command
- ret
- sftype endp
-
- sfcoll proc near ; SET FILE COLLISION
- call srvswk ; get second value to ax
- jc sfcollb ; c = failure
- cmp ax,4
- ja sfcollb ; a = bad
- cmp ax,2 ; backup?
- je sfcollb ; e = yes, bad command
- cmp ax,3 ; append?
- je sfcollb ; e = yes, bad command
- mov flags.flwflg,al ; set file collison state
- clc
- ret
- sfcollb:stc ; bad command
- ret
- sfcoll endp
-
- sfinc proc near ; SET INCOMPLETE, SET FILE INCOMPLETE
- call srvswk ; get second value to ax
- jc sfincb ; c = failure
- cmp ax,1
- ja sfincb ; a = bad
- mov flags.abfflg,al ; discard incomplete files if al = 1
- clc
- ret
- sfincb: stc ; bad command
- ret
- sfinc endp
-
- srtmo proc near ; SET RECEIVE TIMEOUT
- call srvswk ; get second value to ax
- jnc srtmo1 ; nc = success
- ret
- srtmo1: cmp ax,94 ; above limit?
- jbe srtmo2 ; be = no
- mov al,94
- srtmo2: mov trans.rtime,al
- clc
- ret
- srtmo endp
-
- sblkck proc near ; SET BLOCK-CHECK
- call srvswk ; get second value to ax
- jnc sblkck1 ; nc = success
- ret ; fail
- sblkck1:cmp ax,3 ; our limit
- jbe sblkck2 ; be = safe
- mov ax,3 ; set to max
- sblkck2:or ax,ax ; too small?
- jnz sblkck3 ; z = no
- inc ax
- sblkck3:mov dtrans.chklen,al ; use this char as initial checksum
- clc
- ret
- sblkck endp
-
- srpkt proc near ; SET RECEIVE PACKET-LENGTH
- call srvswk ; get second value to ax
- jnc srpkt1 ; nc = success
- ret
- srpkt1: cmp ax,9024 ; above limit?
- jbe srpkt2 ; be = no
- mov ax,9024
- srpkt2: cmp ax,20 ; too small?
- jae srpkt3 ; ae = no
- mov ax,20 ; set minimum
- srpkt3: mov dtrans.rlong,ax ; set long packet size
- mov bl,dtrans.rpsiz ; regular packet size
- xor bh,bh
- cmp ax,bx ; is long packet shorter
- jae srpkt4 ; ae = no
- mov dtrans.rpsiz,al ; set regular pkt length too
- srpkt4: clc
- ret
- srpkt endp
-
- sretry proc near ; REMOTE SET RETRY
- call srvswk ; get second value to ax
- jnc sretry1 ; nc = success
- ret ; fail
- sretry1:cmp ax,63 ; our limit
- jbe sretry2 ; be = safe
- mov ax,63 ; set to max
- sretry2:mov maxtry,al ; set packet retry limit
- clc
- ret
- sretry endp
-
- sstmo proc near ; SET SERVER TIMEOUT
- call srvswk ; get second value to ax
- jnc sstmo1 ; nc = success
- ret
- sstmo1: cmp ax,255
- jbe sstmo2 ; be = in range
- mov al,255 ; limit to max
- sstmo2: mov srvtmo,al ; store timeout value
- clc
- ret
- sstmo endp
-
- sxfrch proc near ; SET TRANSFER CHARACTER-SET string
- mov bx,bufptr
- xor ch,ch
- mov cl,[bx] ; byte count of next field, if any
- sub cl,' ' ; remove ascii bias
- jnc sxfrch1 ; nc = is ok
- ret
- sxfrch1:inc bx ; look at character string
- cmp byte ptr[bx],'A' ; A for Transparent?
- jne sxfrch2
- cmp cx,1 ; just that char?
- jne sxfrchb ; ne = no, fail
- mov trans.xchset,0 ; set transfer char set to Transparent
- clc
- ret
- sxfrch2:cmp cx,6 ; "I2/100"?
- jne sxfrchb ; ne = no, fail
- cmp word ptr [bx],'2I' ; length is ok, check spelling
- jne sxfrchb ; ne = failure
- cmp word ptr [bx+2],'1/'
- jne sxfrchb
- cmp word ptr [bx+4],'00'
- jne sxfrchb
- mov trans.xchset,1 ; set transfer char set to Latin1
- clc
- ret
- sxfrchb:stc ; fail
- ret
- sxfrch endp
-
- swind proc near ; SET WINDOW-SLOTS
- call srvswk ; get second value to ax
- jnc swind1 ; nc = success
- ret
- swind1: cmp ax,31 ; max legal
- jbe swind2 ; be = in range
- mov al,31 ; limit to max
- swind2: or ax,ax ; no windowing?
- jnz swind3 ; nz = no, not that way
- mov ax,1 ; local min size for no windowing
- swind3: mov dtrans.windo,al ; store default window size
- clc
- ret
- swind endp
-
- ; Worker for srvset. Reads buffer pointed at by bufptr looking for
- ; construction <length><numbers>. Returns carry clear and binary number
- ; in AX, else carry set and AX = -1. Bufptr is always updated.
- srvswk proc near
- push bx
- push cx
- push dx
- push si
- mov bx,bufptr
- xor ch,ch
- mov cl,[bx] ; byte count of next field, if any
- sub cl,' ' ; remove ascii bias
- jnc srvswk1 ; nc = is ok
- mov ax,-1 ; else say value is -1
- jmp short srvswkx
- srvswk1:inc bx
- xor si,si ; accumulated value
- mov dl,10
- srvswk2:mov ax,si ; accumulated value
- mul dl ; times 10
- mov si,ax ; store
- xor ah,ah
- mov al,[bx] ; get a digit
- inc bx
- sub al,'0' ; remove ascii bias
- jnc srvswk3 ; nc = no
- mov ax,-1 ; say bad value
- jmp short srvswkx ; and quit
- srvswk3:add si,ax ; accumulate new digit
- loop srvswk2 ; do all digits
- mov ax,si ; return results in ax
- clc
- srvswkx:mov bufptr,bx ; remember where we read from decbuf
- pop si
- pop dx
- pop cx
- pop bx
- ret
- srvswk endp
-
- ; srvini - init parms based on 'I' init packet
- srvini proc near
- call spar ; parse info
- call packlen
- mov cx,trans.rlong ; max receiving pkt length to report
- call makebuf ; remake buffers for new windowing
- push si
- mov si,offset rpacket
- call rpar ; setup info about our reception
- pop si
- mov al,trans.chklen ; checksum length negotiated
- push ax ; save around reply
- mov trans.chklen,1 ; reply with 1 char checksum
- call ackpak
- pop ax ; restore checksum length
- mov dtrans.chklen,al ; to negotiation value
- clc ; success
- ret
- srvini endp
-
-
- ; BYE command - tell remote KERSRV to logout & exit to DOS
-
- BYE PROC NEAR
- mov ah,cmeol ; get a confirm
- call comnd
- jnc bye1 ; nc = success
- ret ; failure
- bye1: mov remcmd,'L' ; Logout command letter
- call logo ; tell the host Kermit to logout
- jc bye2 ; c = failed, do not exit
- ;;; mov flags.extflg,1 ; set this Kermit's exit flag
- call serhng ; hangup the phone
- bye2: clc
- ret
- BYE ENDP
-
- ; FINISH - tell remote KERSRV to exit
-
- FINISH PROC NEAR
- mov ah,cmeol ; get a confirm
- call comnd
- jnc finish1 ; nc = success
- ret ; failure
- finish1:mov remcmd,'F' ; Finish command letter
- call logo
- clc
- ret
- FINISH ENDP
-
- ; Common routine for BYE, FINISH, REMOTE LOGOUT. Avoids sending I packet.
- ; Return carry clear for success, else carry set
- LOGO PROC NEAR
- call serini ; Initialize port
- jnc logo1 ; nc = success
- ret ; c = failure
- logo1: call clrbuf ; clear serial port buffer
- call ihostr ; initialize the host
- mov trans.windo,1 ; one window slot before negotiations
- mov cx,dspsiz ; default send pkt length (94)
- call makebuf ; set up packet buffers
- xor ax,ax
- mov diskio.string,al ; clear local filename for stats
- mov pktnum,al ; packet number to be used
- mov windlow,al ; reset windowing
- call packlen ; get max packet length
- call getbuf ; get buffer for sending
- mov trans.chklen,1 ; use one char for server functions
- mov ah,remcmd ; get command letter ('L' or 'F')
- mov encbuf,ah ; encode the command
- mov cx,1 ; one piece of data
- call doenc ; do encoding
- mov [si].pktype,'G' ; Generic command packet type
- mov flags.xflg,1 ; say receiving to screen
- call sndpak ; to suppress # pkts msg
- jc logo3 ; c = failure
- mov al,[si].seqnum ; get response for this sequence num
- mov ah,maxtry ; retry threshold
- call response ; get response
- pushf
- mov si,offset rpacket ; packet to look at
- cmp [si].pktype,'E' ; Error packet?
- je logo2 ; e = yes, contents displayed already
- call msgmsg ; show any message
- logo2: popf
- logo3: mov flags.cxzflg,0 ; clear these flags
- mov flags.xflg,0
- ret ; exit with carry flag from response
- LOGO ENDP
-
- ; GET command. Ask remote server to send the specified file(s)
- ; Queries for remote filename and optional local override path/filename
- GET PROC NEAR
- mov auxfile,0 ; clear, for safety
- mov encbuf,0 ; ditto
- mov flags.cxzflg,0 ; no Control-C typed yet
- mov bx,offset encbuf ; where to put text
- mov dx,offset filmsg ; help
- mov ah,cmline ; filenames with embedded whitespace
- call comnd ; get text or confirm
- jnc get1 ; nc = success
- ret ; failure
- get1: mov cnt,ax ; remember number of chars we read
- or ax,ax ; read in any chars?
- jnz get7 ; nz = yes, analyze
- ; if empty line, ask for file names
- get2: mov dx,offset remfnm ; ask for remote name first
- call prompt
- mov bx,offset encbuf ; place for remote filename
- mov dx,offset frem ; help message
- mov ah,cmline ; use this for embedded spaces
- call comnd ; get a filename
- jnc get3 ; nc = success
- ret ; failure
- get3: mov cnt,ax ; remember number of chars read
- or ax,ax ; count of entered chars
- jz get2 ; z = none, try again
- mov dx,offset lclfnm ; prompt for local filename
- call prompt
- mov bx,offset filhlp
- mov dx,offset auxfile ; complete local filename
- mov auxfile,0 ; clear, for safety
- mov ah,cmword ; get a word
- call comnd
- jnc get5 ; nc = success
- ret ; failure
- get5: mov ah,cmeol ; get confirmation
- call comnd
- jnc get6 ; nc = success
- ret ; failure
- get6: cmp auxfile,'#' ; is first char a replacement for '?'
- jne get7 ; ne = no
- mov auxfile,'?' ; replace '#' by '?'
- get7: cmp encbuf,'#' ; is first char a replacement for '?' ?
- jne get8 ; ne = no
- mov encbuf,'?' ; replace '#' by '?'
-
- get8: call rrinit ; get & clear buffers and counters
- mov flags.xflg,1 ; assume writing to screen
- cmp flags.destflg,2 ; receiving to screen?
- je get8a ; e = yes, skip screen stuff
- mov flags.xflg,0 ; not writing to screen, yet
- call init ; init (formatted) screen
- get8a: mov kstatus,kssuc ; global status, success
- call ipack ; Send Initialize, 'I', packet
- jnc get8b ; nc = success, ok to fail 'I' pkt
- jmp short get10 ; failure
-
- get8b: mov si,offset encbuf ; copy from here
- mov di,offset fsta.xname ; to statistics remote name field
- call strcpy
- mov si,offset rpacket ; packet for response
- mov cx,cnt ; get back remote filename size
- call doenc ; encode data already in encbuf
- jnc get9 ; nc = success
- mov dx,offset ermes6 ; filename is too long for pkt
- call ermsg
- mov bx,dx ; point to message, for errpack
- call errpack ; tell the host we are quiting
- jmp short get10 ; data could not all fit into packet
-
- get9: mov trans.chklen,1 ; use one char for server functions
- mov rpacket.pktype,'R' ; Receive init packet
- mov si,offset rpacket
- call sndpak ; send the packet, no ACK expected
- jc get10 ; c = failure to send packet
- mov rstate,'R' ; Set the state to receive initiate
- jmp READ2 ; go join read code
-
- get10: call bufclr ; total failures come here
- call rprpos ; reset cursor for prompt
- or errlev,ksrecv ; set DOS error level to cannot rcv
- or fsta.xstatus,ksrecv ; set status
- mov kstatus,ksrecv ; global status
- mov flags.cxzflg,0 ; clear flag for next command
- mov auxfile,0 ; clear send-as filename buffer
- mov flags.xflg,0 ; clear to-screen flag
- mov al,1 ; underline cursor
- call fcsrtype ; set IBM-PC cursor to underline
- clc
- ret
- GET ENDP
-
- ; This is the REMOTE command
-
- REMOTE PROC NEAR
- mov dx,offset remtab ; Parse keyword from the REMOTE table
- mov bx,offset remhlp
- mov ah,cmkey
- call comnd
- jnc remote1 ; nc = success
- ret ; failure
- remote1:jmp bx ; do the appropriate routine
- REMOTE ENDP
-
- ; REMSET - Execute a REMOTE SET command
-
- REMSET PROC NEAR
- mov rempac,'G' ; Packet type = generic
- mov encbuf,'S' ; command type = Set
- mov bufptr,offset encbuf+1 ; place more pkt material here
- mov ah,cmkey ; get keyword
- mov dx,offset remstt1 ; table of keywords
- xor bx,bx ; help
- call comnd
- jnc remset1 ; nc = success
- ret
- remset1:cmp bx,1 ; Attributes?
- jne remset5 ; ne = no
- mov dx,offset remsat1 ; Attributes IN, OUT table
- xor bx,bx ; help
- mov ah,cmkey
- call comnd
- jnc remset2
- ret
- remset2:mov temp,bx ; save in out
- mov dx,offset remsat2 ; next attributes keyword table
- xor bx,bx ; help
- mov ah,cmkey
- call comnd
- jnc remset3
- ret
- remset3:add bx,temp ; save final value
- call remwork
- mov dx,offset onoff ; ON, OFF table
- xor bx,bx ; help
- mov ah,cmkey ; get on,off
- call comnd
- jnc remset4
- ret
- remset4:jmp remset17
-
- remset5:cmp bx,2 ; REMOTE SET FILE?
- jne remset14 ; ne = no
- mov dx,offset remsfit ; REM SET FILE table
- xor bx,bx ; help
- mov ah,cmkey
- call comnd
- jnc remset6
- ret
- remset6:push bx
- call remwork ; write kind to buffer
- pop bx
- cmp bx,300 ; TYPE?
- jne remset8
- mov dx,offset remsfty ; TYPE table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset17
- ret
-
- remset8:cmp bx,301 ; NAME?
- jne remset10 ; ne = no
- mov dx,offset remsfna ; NAME table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset17
- ret
-
- remset10:cmp bx,302 ; COLLISION?
- jne remset12 ; ne = no
- mov dx,offset remsfco ; COLLISION table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset17
- ret
-
- remset12:cmp bx,303 ; REPLACE?
- jne remset13 ; ne = no
- mov dx,offset remsfre ; REPLACE table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset17
- ret
-
- remset13:cmp bx,310 ; INCOMPLETE?
- jne remset13a ; ne = no
- mov dx,offset remsfin ; INCOMPLETE table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset17
- remset13a:stc
- ret
-
- remset14:cmp bx,310 ; REMOTE SET INCOMPLETE?
- jne remset15 ; ne = no
- push bx
- call remwork ; write main command
- pop bx
- jmp short remset13 ; use above to complete the command
-
- remset15:cmp bx,3 ; REMOTE SET RECEIVE?
- jne remset18 ; ne = no
- mov dx,offset remsrcv ; RECEIVE table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset19 ; get value as text
- remset16:stc
- ret
-
- remset17:call remwork ; write to buffer
- jmp short remset22
- ; text as last item commands
- remset18:mov temp,bx
- cmp bx,405 ; Transfer?
- jne remset19 ; ne = no
- mov dx,offset remsxfr ; TRANSFER table
- xor bx,bx
- mov ah,cmkey
- call comnd
- jnc remset19
- ret
- remset19:call remwork ; store command type
- mov dx,bufptr ; store response as text
- inc dx ; skip count byte
- mov bx,offset numhlp
- cmp temp,405 ; Transfer character set needs string
- jne remset20 ; ne = not string
- mov bx,offset xfrhlp ; use this help
- remset20:mov ah,cmword
- call comnd
- jnc remset21
- ret
- remset21:mov dx,bufptr ; field pointer
- inc dx ; look at text
- call strlen ; length to cx
- add cx,' ' ; compute byte count field
- mov bx,bufptr
- mov [bx],cl ; store byte count
-
- remset22:mov ah,cmeol ; get a confirmation
- call comnd
- jnc remset23
- ret
- remset23:mov dx,offset encbuf
- call strlen ; get length
- mov cnt,cx ; length for generic
- mov flags.xflg,1 ; response coming to screen
- jmp genr9 ; do the operation
- REMSET ENDP
-
- ; Remote Set worker. Enter with new numerical value in BX. Writes length
- ; and asciiz value to encbuf and increments buffer pointer bufptr.
- remwork proc near
- mov di,offset tmpbuf ; temp buffer
- mov byte ptr [di],0 ; clear it
- mov ax,bx
- call dec2di ; convert value to asciiz
- mov dx,offset tmpbuf ; get length to cx
- mov si,dx ; asciiz data source
- call strlen
- push cx ; save length
- mov di,bufptr ; byte count field
- add cl,' ' ; to ascii
- mov [di],cl ; store count byte
- inc di
- pop cx
- push es
- push ds
- pop es
- cld
- rep movsb ; copy asciiz data value
- pop es
- mov byte ptr [di],0 ; insert null terminator
- mov bufptr,di
- ret
- remwork endp
-
- ; In REM commands below, al = remcmd, ah = rempac, cl = remlen
- ; REMCWD - Change remote working directory
-
- REMCWD PROC NEAR
- mov ax,'GC' ; Packet type = generic
- xor cl,cl ; no text required
- jmp genric
- REMCWD ENDP
-
- ; REMDEL - Delete a remote file
-
- REMDEL PROC NEAR
- mov ax,'GE' ; Packet type = generic
- mov cl,1 ; text required
- jmp genric
- REMDEL ENDP
-
- ; REMDIR - Do a directory
-
- REMDIR PROC NEAR
- mov ax,'GD' ; Packet type = generic
- xor cl,cl ; no text required
- jmp genric
- REMDIR ENDP
-
- ; REMDIS - Get disk usage on remote system
-
- REMDIS PROC NEAR
- mov ax,'GU' ; Packet type = generic, disk usage
- xor cl,cl ; optional text permitted
- jmp genric ; Execute generic Kermit command
- REMDIS ENDP
-
-
- ; REMHEL - Get help about remote commands
-
- REMHEL PROC NEAR
- mov ax,'GH' ; Packet type = generic, Help
- xor cl,cl ; no text required
- jmp genric ; Execute generic Kermit command
- REMHEL ENDP
-
- ; REMHOS - Execute a remote host command
-
- REMHOS PROC NEAR
- mov ax,'C ' ; Packet type = remote command
- mov cl,1 ; text required
- jmp genric
- REMHOS ENDP
-
- ; REMKER - Execute a remote Kermit command
-
- REMKER PROC NEAR
- mov ax,'K ' ; Packet type = remote Kermit command
- mov cl,1 ; text required
- jmp short genric
- REMKER ENDP
-
- ; REMLOGIN - LOGIN [username [password [account]]]
-
- REMLOGIN PROC NEAR
- mov ax,'GI' ; Packet type = generic
- xor cl,cl ; no text required
- jmp short genric
- REMLOGIN ENDP
-
- ; REMOTE LOGOUT - Logout of remote server and host, stay in this Kermit
- REMLOGOUT PROC NEAR
- mov remcmd,'L' ; Logout command letter
- call logo ; perform without I packet
- clc
- ret
- REMLOGOUT ENDP
-
- ; REMMSG - Send one line short message to remote screen.
-
- REMMSG proc near
- mov ax,'GM'
- mov cl,1 ; text required
- jmp short genric
- REMMSG endp
-
- ; REMTYP - Type a remote file
-
- REMTYP PROC NEAR
- mov ax,'GT' ; Packet type = generic, Type file
- mov cl,1 ; text required
- jmp short genric
- REMTYP ENDP
-
- ; REMWHO - ask for list of remote logged on users
-
- REMWHO proc near
- mov ax,'GW'
- xor cl,cl ; optional text permitted
- jmp short genric
- REMWHO endp
-
- ; GENRIC - Send a generic command to a remote Kermit server
- ; remlen = 0: no additional text, or additional text is optional
- ; remlen = 1: additional text is required
- GENRIC PROC NEAR
- mov remcmd,al ; stash cmd info in real memory
- mov rempac,ah ; packet type
- mov remlen,cl ; text required flag
- mov si,offset infms3 ; dummy filename for transaction log
- mov di,offset diskio.string ; where such names go
- call strcpy ; move the name
- mov bx,offset encbuf ; where to put text
- mov temp,bx ; where field starts
- cmp rempac,'C' ; Remote Host command?
- je genr2 ; e = yes, no counted string(s)
- cmp rempac,'K' ; Remote Kermit command?
- je genr2 ; e = yes, no counted string(s)
- genr1: mov ah,remcmd ; get command letter
- mov [bx],ah ; store in buffer
- add bx,2 ; leave room for count byte
- mov temp,bx ; point at data field
- genr2: mov ah,cmline ; get a line text
- mov dx,offset genmsg ; help message
- call comnd
- jnc genr3 ; nc = success
- ret ; failure
- genr3: mov cnt,ax ; size
- call genredir ; act on any ">filespec" redirection
- add temp,ax ; point to next field
- cmp rempac,'C' ; Remote Host command?
- je genr4 ; e = yes, no counted string(s)
- cmp rempac,'K' ; Remote Kermit command?
- je genr4 ; e = yes, no counted string(s)
- mov encbuf+1,al ; size of first field
- add encbuf+1,32 ; do tochar function
- inc temp ; include count byte
- genr4: cmp al,remlen ; got necessary command text?
- jae genr5 ; ae = yes
- cmp remlen,0 ; is text optional?
- je genr5 ; e = yes, continue without it
- genr4a: mov dx,offset infms2 ; say need more info
- mov ah,prstr
- int dos
- or errlev,ksgen ; say cannot receive
- or fsta.xstatus,ksgen ; set status failed
- mov kstatus,ksgen ; global status
- clc
- ret
-
- genr5: mov flags.xflg,1 ; output coming to screen
- cmp remcmd,'I' ; Remote Login command?
- je genr6 ; e = yes
- cmp remcmd,'C' ; Remote Change Working Directory?
- je genr7a ; e = yes, get optional password
- jmp short genr8 ; neither so no extra prompts here
-
- genr6: cmp cnt,0 ; have username etc already?
- je genr6a ; e = no
- call genupwd ; parse username etc
- jmp short genr8 ; send formatted contents
- genr6a: mov dx,offset user ; prompt for username
- call prompt
- mov bx,offset encbuf+1 ; skip command letter
- mov temp,bx ; start of field
- call input ; read text
- jc genr8 ; c = none
- mov temp,bx ; point to next data field
-
- genr7: mov dx,offset password ; get optional password
- call prompt
- genr7a: mov bx,temp ; where to put the password
- cmp byte ptr [bx-1],0 ; extra null?
- jne genr7b ; ne = no
- dec bx ; backup to overwrite it
- dec temp
- genr7b: mov comand.cmquiet,1 ; turn on quiet mode
- call input ; read in the password
- mov comand.cmquiet,0 ; turn off quiet mode
- jc genr8 ; c = no text, do not add field
- mov temp,bx ; point to next data field
- ;
- cmp remcmd,'I' ; Remote Login command?
- jne genr8 ; ne = no
- mov dx,offset account ; get optional account ident
- call prompt
- mov bx,temp ; where this field starts
- call input ; read text
- genr8: cmp flags.cxzflg,'C' ; Control-C entered?
- jne genr9 ; ne = no
- stc
- ret ; return failure
-
- GENR9: mov kstatus,kssuc ; global status
- call ipack ; Send Init parameters
- jc genr11 ; c = failure
- mov trans.chklen,1 ; use 1 char for server functions
- mov fsta.pretry,0 ; no retries yet
- mov pktnum,0
- cmp flags.cxzflg,'C' ; did the user type a ^C?
- jne genr10 ; ne = no
- stc
- ret ; return in error state
-
- genr10: push si
- mov si,offset rpacket ; use this packet for reply
- mov dx,offset encbuf
- call strlen ; length of data
- call doenc ; encode data
- mov trans.chklen,1 ; use block check 1 to server
- mov ah,rempac ; packet type
- mov rpacket.pktype,ah
- call sndpak ; send the Generic command packet
- pop si
- jc genr11 ; c = failure
- mov rstate,'R' ; next state is Receive Initiate
- jmp READ2 ; file receiver does the rest
-
- genr11: mov flags.xflg,0 ; reset screen output flag
- xor ax,ax ; tell statistics this was a read
- or errlev,ksrem ; DOS error level, failure of REMote cmd
- mov fsta.xstatus,ksrem ; set status
- mov kstatus,ksrem ; global status
- clc
- ret
- GENRIC ENDP
-
- ; Extract ">filespec" redirection at end of command line. If found put
- ; filespec in auxfile as new output name.
- genredir proc near
- mov cx,cnt ; chars on command line
- jcxz genred3 ; z = none
- mov di,temp ; buffer, after prologue
- add di,cx ; end of buffer+1
- dec di
- push ax
- push es
- mov ax,ds
- mov es,ax
- mov al,'>' ; redirection symbol
- std ; scan backward
- repne scasb ; found '>'?
- cld
- pop es
- pop ax
- jne genred3 ; ne = no
- inc di ; look at '>'
- mov byte ptr[di],0 ; insert terminator
- mov ax,cx ; new count length
- mov cnt,cx ; remember here too
- genred1:inc di ; look at optional filename
- or di,di ; terminator?
- jz genred2 ; z = yes
- cmp byte ptr [di],' ' ; remove lead-in puncutation
- jbe genred1 ; be = punctuation, go until text
- genred2:mov si,di
- mov di,offset auxfile ; new output name goes here
- call strcpy
- genred3:ret
- genredir endp
-
- ; Parse a single command line into username, password, account in counted
- ; string style, for REM LOGIN. Enter with BX pointing at the next new
- ; byte to store a command character and CNT holding the current line length.
- ; Returns a completely formatted line, asciiz. Use {..} to surround items
- ; with embedded spaces.
- genupwd proc near
- push ax
- push bx
- push es
- mov ax,ds
- mov es,ax
- sub bx,cnt ; next item minus count of items
- mov si,bx ; where text starts
- dec bx ; point at count byte
- mov cx,3 ; three fields possible
- genupw1:push cx
- mov cx,cnt ; number of text chars to examine
- call genup10 ; get first field
- mov cnt,cx ; update remaining count
- or cx,cx ; get remaining count
- pop cx ; recover loop counter
- jz genupw2 ; z means empty remainder
- loop genupw1 ; try to do three fields
- genupw2:pop es
- pop bx
- pop ax
- ret
-
- ; Worker. Enter with bx=offset of count byte, si=offset of start of text,
- ; cx=chars remaining in input string.
- ; Exit with bx=offset of next count byte, si=offset of where new text is
- ; to be read, cx=chars remaining in input string.
- genup10:mov byte ptr [bx],' ' ; clear count byte to zero + space
- mov di,si ; work on text part
- mov al,' ' ; skip whitespace
- cld
- repe scasb
- je genup12 ; e = nothing present
- dec di ; back up to non-white char
- inc cx ; correct count
- mov si,di ; si = where non-white text starts
- mov di,bx ; count byte
- inc di ; where text goes
- mov ah,' ' ; assume this is the break char
- cmp byte ptr [si],'{' ; field starts with brace?
- jne genup11 ; ne = no
- mov ah,'}' ; use this break char
- inc si ; skip over leading brace
- dec cx ; one less char to consider
- genup11:lodsb ; get a char
- cmp al,ah ; break char yet?
- je genup12 ; e = yes
- or al,al ; end of text?
- jz genup12 ; z = yes
- stosb ; store char without leading padding
- inc byte ptr [bx] ; count chars stored in this field
- loop genup11 ; continue
- genup12:mov bx,di ; where to store next count byte
- mov byte ptr [di],0 ; null terminator
- ret
- genupwd endp
-
- ; Send "I" packet with transmission parameters
-
- IPACK PROC NEAR
- call serini ; initialize serial port
- jnc ipack1
- ret ; c = failure
- ipack1: call ihostr ; initialize the host
- call clrbuf ; clear serial port buffer
- call sparmax ; set up our maximum capabilites
- mov trans.windo,1 ; no windows yet
- mov cx,dspsiz ; default send pkt length (94)
- call makebuf ; remake buffers
- xor ax,ax
- mov rpacket.numtry,al ; number of receive retries
- mov fsta.pretry,ax ; no retries
- mov pktnum,al ; packet number 0
- mov windlow,al ; reset windowing
- call packlen ; compute packet length
- call getbuf ; get buffer for sending
- call rpar ; store them in the packet
- mov trans.chklen,1 ; one char for server function
- mov [si].pktype,'I' ; "I" packet
- call sndpak ; send the packet
- jnc ipack2 ; nc = success
- ret ; return failure
- ipack2: mov al,[si].seqnum
- mov ah,maxtry ; retry threshold
- add ah,ah
- add ah,maxtry ; triple the normal retries
- mov chkparflg,1 ; check for unexpected parity
- call response ; get response
- jnc ipack3 ; nc = success
- call bufclr ; clear all
- cmp rpacket.pktype,'E' ; was it an Error pkt response?
- je ipack4 ; e = yes, this is forgivable
- stc ; carry set for failure
- ret ; return failure
-
- ipack3: cmp rpacket.pktype,'Y' ; ACK response?
- jne ipack4 ; ne = no
- push si
- mov si,offset rpacket ; packet address
- call spar ; read in the data
- pop si
- call packlen ; get max send packet size
- mov cx,trans.rlong ; max receiving pkt length to report
- call makebuf ; remake buffers for new windowing
- ipack4: cmp rpacket.pktype,'E' ; was it an Error pkt response?
- jne ipack5 ; ne = no
- mov dx,offset emptymsg ; clear last error line
- call ermsg ; do it
- ipack5: clc
- ret ; return success
- IPACK ENDP
-
- ; Returns BX the updated pointer to the input buffer
- ; input buffer = <ascii data length count byte>textstring
- ; return carry clear if have text, else carry set for none
- INPUT PROC NEAR
- mov temp2,bx ; where to put byte count
- inc bx ; start text after count byte
- xor dx,dx ; help, none
- mov ah,cmline ; get text with embedded whitespace
- call comnd
- jnc input1 ; nc = success
- mov bx,temp2 ; empty field, restore pointer
- ret ; failure
- input1: push bx
- mov bx,temp2
- add al,' ' ; convert byte count to ascii
- mov [bx],al ; store count byte
- pop bx ; return pointer to next free byte
- clc ; say have bytes
- ret
- INPUT ENDP
-
- code ends
- end
-